package com.sqx.modules.course.util;

// 各种excepting 可自定义，或者直接改成 Exception

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.sqx.common.exception.SqxException;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.bytedeco.ffmpeg.avcodec.AVCodec;
import org.bytedeco.ffmpeg.ffmpeg;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.presets.avutil;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.filtergraphs.OverlayWatermark;
import ws.schild.jave.filters.DrawtextFilter;
import ws.schild.jave.filters.helpers.OverlayLocation;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.info.VideoSize;
import ws.schild.jave.process.ProcessWrapper;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;
import ws.schild.jave.Encoder;
import com.sqx.modules.file.AliFileUploadController;
import org.bytedeco.opencv.opencv_core.IplImage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ws.schild.jave.progress.EncoderProgressListener;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class FfmpegUtil {

    /**
     * 获取音视频时长
     *
     * @param sourcePath  视频路径
     * @return
     * @throws EncoderException
     */
    public static long getFileDuration(String sourcePath) throws EncoderException {
        MultimediaObject multimediaObject = new MultimediaObject(new File(sourcePath));
        MultimediaInfo multimediaInfo = multimediaObject.getInfo();
        return multimediaInfo.getDuration();
    }

    /**
     * 剪切音视频
     *
     * @param sourcePath
     * @param targetPath
     * @param offetTime   起始时间，格式 00:00:00.000   小时:分:秒.毫秒
     * @param endTime   同上
     * @throws Exception
     */
    public static void cutAv(String sourcePath, String targetPath, String offetTime, String endTime) {
        //获取视频时长
        System.out.println("offetTime = " + offetTime);
        System.out.println("endTime = " + endTime);
        try {
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(sourcePath);
            ffmpeg.addArgument("-ss");
            ffmpeg.addArgument(offetTime);
            ffmpeg.addArgument("-t");
            ffmpeg.addArgument(endTime);
            ffmpeg.addArgument("-vcodec");
            ffmpeg.addArgument("copy");
            ffmpeg.addArgument("-acodec");
            ffmpeg.addArgument("copy");
            ffmpeg.addArgument(targetPath);
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("切除视频成功={}", targetPath);
        } catch (IOException e) {
            throw new SqxException("剪切视频失败",501);
        }
    }

    /**
     * 等待命令执行成功，退出
     *
     * @param br
     * @throws IOException
     */
    private static void blockFfmpeg(BufferedReader br) throws IOException {
        String line;
        // 该方法阻塞线程，直至合成成功
        while ((line = br.readLine()) != null) {
            doNothing(line);
        }
    }

    /**
     * 打印日志，调试阶段可解开注释，观察执行情况
     *
     * @param line
     */
    private static void doNothing(String line) {
//    log.info(line);
    }

    /**
     * 合并两个视频
     *
     * @param firstFragmentPath   资源本地路径或者url
     * @param secondFragmentPath  资源本地路径或者url**
     * @param targetPath     目标存储位置
     * @throws Exception
     */
    public static HashMap<String,Object> mergeAv(String firstFragmentPath, String secondFragmentPath,
                                  String targetPath) {
        try {
            // 执行 ffmpeg -version 命令
            Process process = Runtime.getRuntime().exec("ffmpeg -version");
            // 读取命令的输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine())!= null) {
                System.out.println(line);
            }
            log.info("合并视频处理中firstFragmentPath={},secondFragmentPath={},请稍后.....", firstFragmentPath,
                    secondFragmentPath);
            // 创建一个FFMPEG执行器
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            // 添加第一个输入文件
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(firstFragmentPath);
            // 添加第二个输入文件
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(secondFragmentPath);
            // 添加过滤器复杂参数
            ffmpeg.addArgument("-filter_complex");
            // 添加合并参数
            ffmpeg.addArgument(
                    "\"[0:v] [0:a] [1:v] [1:a] concat=n=2:v=1:a=1 [v] [a]\" -map \"[v]\" -map \"[a]\"");
            //添加输出视频编码
            ffmpeg.addArgument("-vcodec");
            ffmpeg.addArgument("libx264");
            ffmpeg.addArgument("-c:a");
            ffmpeg.addArgument("copy");
            // 添加输出文件
            ffmpeg.addArgument(targetPath);
            // 执行命令
            ffmpeg.execute();
            // 等待命令执行成功，退出
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("合并视频成功={}", targetPath);
            HashMap<String,Object> map = new HashMap<>();
//            MultimediaInfo videoInfo = getVideoInfo(targetPath, 2);
            return map;
        } catch (IOException e) {
            throw new SqxException("合并视频失败",501);
        }
    }

    /**
     * 获取视频原声
     *
     * @param sourcePath  本地路径或者url
     * @param targetPath  本地存储路径
     */
    public static String getAudio(String sourcePath, String targetPath, String taskId) {
        try {
            // 创建一个FFMPEG执行器
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            // 添加输入文件
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(sourcePath);
            // 添加输出文件
            ffmpeg.addArgument("-f");
            // 添加输出格式
            ffmpeg.addArgument("mp3");
            // 添加输出文件
            ffmpeg.addArgument("-vn");
            // 添加输出文件
            ffmpeg.addArgument(targetPath);
            // 执行命令
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("获取视频音频={}", targetPath);
        } catch (IOException e) {
            throw new SqxException("获取视频音频失败",501);
        }
        return targetPath;
    }

    /**
     * 合并音频
     *
     * @param originAudioPath  音频url或本地路径
     * @param magicAudioPath  音频url或本地路径
     * @param audioTargetPath  目标存储本地路径
     */
    public static void megerAudioAudio(String originAudioPath, String magicAudioPath,
                                       String audioTargetPath, String taskId) {
        try {
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(originAudioPath);
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(magicAudioPath);
            ffmpeg.addArgument("-filter_complex");
            ffmpeg.addArgument("amix=inputs=2:duration=first:dropout_transition=2");
            ffmpeg.addArgument("-f");
            ffmpeg.addArgument("mp3");
            ffmpeg.addArgument("-y");
            ffmpeg.addArgument(audioTargetPath);
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("合并音频={}", audioTargetPath);
        } catch (IOException e) {
            throw new SqxException("合并音频失败",501);
        }
    }

    /**
     * 视频加声音
     *
     * @param videoPath   视频
     * @param megerAudioPath  音频
     * @param videoTargetPath 目标地址
     * @param taskId  可忽略，自行删除taskid
     * @throws Exception
     */
    public static void mergeVideoAndAudio(String videoPath, String megerAudioPath,
                                          String videoTargetPath, String taskId) {
        try {
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(videoPath);
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(megerAudioPath);
            ffmpeg.addArgument("-codec");
            ffmpeg.addArgument("copy");
            ffmpeg.addArgument("-shortest");
            ffmpeg.addArgument(videoTargetPath);
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("获取视频(去除音频)={}", videoTargetPath);
        } catch (IOException e) {
            throw new SqxException("获取视频(去除音频)失败",501);
//            throw new CombineException(ResultCode.ERROR.getCode(), "获取视频(去除音频)失败", taskId);
        }
    }

    /**
     * 图片生成视频   帧率设置25，可自行修改
     *
     * @param videoPath
     * @param videoPath
     * @return
     * @throws Exception
     */
    public static boolean picToVideo(String picsPath, String videoPath, String taskId) {
        try {
            log.info("图片转视频中....");
            ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
            ffmpeg.addArgument("-i");
            ffmpeg.addArgument(picsPath);
            ffmpeg.addArgument("-r");
            ffmpeg.addArgument("25");
            ffmpeg.addArgument("-y");
            ffmpeg.addArgument(videoPath);
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                blockFfmpeg(br);
            }
            log.info("图片转视频成功={}", videoPath);
        } catch (IOException e) {
            log.error("图片转视频失败={}", e.getMessage());
            throw new SqxException("图片转视频失败",501);
//            throw new PicException(ResultCode.ERROR.getCode(), "图片转视频失败", taskId);
        }
        return true;
    }


    /**
     * 获取视频信息
     * format=mov：表示多媒体文件的格式为 MOV。
     * duration=13770：表示多媒体文件的总时长，单位通常是毫秒。
     * video：包含视频相关的信息。
     *     decoder=h264 (High) (avc1 / 0x31637661)：视频的解码器类型为 H.264 高版本。
     *     size=ws.schild.jave.info.VideoSize (width=720, height=1280)：视频的分辨率为宽度 720 像素，高度 1280 像素。
     *     bitRate=2867000：视频的比特率为 2867000 比特每秒。
     *     frameRate=29.92：视频的帧率为 29.92 帧每秒。
     * audio：包含音频相关的信息。
     *     decoder=aac (LC) (mp4a / 0x6134706D)：音频的解码器类型为 AAC 低复杂度（LC）。
     *     samplingRate=44100：音频的采样率为 44100 赫兹。
     *     channels=2：音频的声道数为 2 声道。
     *     bitRate=128000：音频的比特率为 128000 比特每秒。
     * @param url
     * @return
     */
    public static MultimediaInfo getVideoInfo(String url,int type) {
        log.info("获取视频信息={}", url);
        if (ObjectUtils.isEmpty(url)){
            return null;
        }
        try {
            MultimediaObject multimediaObject = null;
            if (type==1){
                multimediaObject = new MultimediaObject(new URL(url));
            }else if (type==2){
                multimediaObject = new MultimediaObject(new File(url));
            }
            return multimediaObject.getInfo();
        } catch (EncoderException e) {
            log.error("获取视频信息报错={}", e.getMessage());
//            throw new SqxException("获取视频信息报错",501);
            e.printStackTrace();
            return null;
        } catch (MalformedURLException e) {
//            throw new RuntimeException(e);
            e.printStackTrace();
            return null;
        }
    }


//    public static void adjustVideoQuality(String inputPath, String outputPath, int targetBitrate) {
//        try {
//            // 创建多媒体对象
//            MultimediaObject multimediaObject = new MultimediaObject(new TFile(inputPath));
//
//            // 设置视频属性
//            VideoAttributes videoAttributes = new VideoAttributes();
//            videoAttributes.setSize(new VideoSize(1280, 720));  // 设置目标分辨率，根据需要修改
//            videoAttributes.setBitRate(targetBitrate);  // 设置目标码率
//
//            // 设置编码属性
//            EncodingAttributes encodingAttributes = new EncodingAttributes();
//            encodingAttributes.setOutputFormat("mp4");  // 输出格式
//            encodingAttributes.setVideoAttributes(videoAttributes);
//
//            // 执行编码
//            Encoder encoder = new Encoder();
//            encoder.encode(multimediaObject, new File(outputPath), encodingAttributes);
//
//            System.out.println("视频清晰度调整成功！");
//        } catch (EncoderException | IOException e) {
//            e.printStackTrace();
//        }
//    }

    /**
     * 给视频添加文字水印
     * @param filePath 视频路径
     * @param text 文字
     */
    public static void codecToMp4WithText(String filePath, String text){
        File file=new File(filePath);
        // 创建FFmpegFrameGrabber对象
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
        //
        Frame frame = null;
        FFmpegFrameRecorder recorder = null;
        String fileName = null;
        try{
            frameGrabber.setFormat("mp4");
            // 开始读取视频文件
            frameGrabber.start();
            Random random=new Random();
            fileName = file.getAbsolutePath() + random.nextInt(100)+".mp4";
            System.out.println("文件名-->>"+fileName);
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
//            recorder.setFormat("mp4");
            recorder.setSampleRate(frameGrabber.getSampleRate());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setTimestamp(frameGrabber.getTimestamp());
            recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
            recorder.setVideoCodec(frameGrabber.getVideoCodec());
            //开始处理视频
            recorder.start();
            int index=0;
            while (true){
                frame=frameGrabber.grabFrame();
                if(frame==null){//循环处理帧，直到为null结束循环
                    System.out.println("视频处理完成");
                    break;
                }
                //判断音频
                System.out.println("音频=="+(frame.samples ==null)+"视频=="+ (frame.image==null));
                //判断图片帧
                if(frame.image !=null){
                    IplImage iplImage = Java2DFrameUtils.toIplImage(frame);
                    BufferedImage buffImg=Java2DFrameUtils.toBufferedImage(iplImage);
                    //创建一个Graphics2D对象
                    Graphics2D graphics = buffImg.createGraphics();
                    //设置字体颜色
                    graphics.setColor(Color.WHITE);
                    //设置字体样式
                    graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
                    //设置字体位置
                    graphics.drawString(text,(iplImage.width()/2)-100,iplImage.height()/2);
                    //释放资源
                    graphics.dispose();
                    //转换成帧
                    Frame newFrame = Java2DFrameUtils.toFrame(buffImg);
                    //设置帧
                    recorder.record(newFrame);
                }
                //设置音频
                if(frame.samples !=null){

                    recorder.recordSamples(frame.sampleRate,frame.audioChannels,frame.samples);
                }
                System.out.println("帧值="+index);
                index ++;
            }
            //关闭
            recorder.stop();
            //释放
            recorder.release();
            //关闭
            frameGrabber.stop();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 调整视频清晰度（未测试）
     * @param inputPath 输入视频路径
     * @param outputPath 输出视频路径
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @throws FFmpegFrameRecorder.Exception
     * @throws FrameGrabber.Exception
     */
    public static void adjustVideoQuality(String inputPath, String outputPath, int targetWidth, int targetHeight) throws FFmpegFrameRecorder.Exception, FrameGrabber.Exception {
        try {
            // 创建输入和输出帧抓取器
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputPath);
            grabber.start();
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputPath, targetWidth, targetHeight);
            AVCodec codec = avcodec.avcodec_find_decoder(avcodec.AV_CODEC_ID_H264); // 设置视频编码器
            recorder.setVideoCodec(codec.id());
            recorder.setFormat("mp4");
            recorder.setFrameRate(grabber.getFrameRate());
            recorder.setVideoBitrate(grabber.getVideoBitrate());
            recorder.start();

            // 读取和写入帧
            Frame frame;
            while ((frame = grabber.grabFrame()) != null) {
                recorder.record(frame);
            }

            // 关闭资源
            grabber.stop();
            grabber.release();
            recorder.stop();
            recorder.release();

            System.out.println("视频清晰度调整成功！");
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 转换视频清晰度（降低后报使用了不受支持的编码设置）
     * @param inputPath
     * @param outputPath
     */
    public static void frameRecord(String inputPath, String outputPath){
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputPath);
        grabber.setOption("rtsp_transport", "tcp"); // 设置rtsp传输协议为tcp
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputPath, 2); // 设置输出视频的帧率
        recorder.setFrameRate(29.92);
        recorder.setVideoBitrate(720*576);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 设置视频编码器
        try {
            recordByFrame(grabber,recorder);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

    public static void recordByFrame(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder)throws Exception{
        try {// 建议在线程中使用该方法

            grabber.start();
//            CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口
//                 canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//            canvas.setAlwaysOnTop(true);
            recorder.setImageHeight(grabber.getImageHeight());
            recorder.setImageWidth(grabber.getImageWidth());
            recorder.start();
            long t1 = System.currentTimeMillis();

            Frame frame = null;


            while (true && (frame = grabber.grabFrame()) != null) {
                long t2 = System.currentTimeMillis();
                if (t2 - t1 > 2 * 60 * 60 * 1000) {
                    break;
                } else {
//视频转音频                    grabber.grabSamples();
                    recorder.record(frame);
                    //TODO your work
                }
                //canvas.showImage(grabber.grab());//获取摄像头图像并放到窗口上显示， 这里的Frame frame=grabber.grab(); frame是一帧视频图像
            }
            recorder.stop();
            grabber.stop();

        } finally {
            IOUtils.closeQuietly(recorder);
            IOUtils.closeQuietly(grabber);
        }
    }

    /**
     * 修改视频的清晰度
     * @param imagePath  原视频地址
     * @param outputDir  输出目录
     * @param width  需要调整的宽度
     * @param height  高度
     * @param bitRate  码率（码率为null，默认使用2000）
     * @return
     * @throws Exception
     */
    public static String modifyResolution(String imagePath,String outputDir,int width, int height,Integer bitRate)throws Exception{
        if (bitRate==null){
            bitRate = 2000;
        }
        List<String> paths = Splitter.on(".").splitToList(imagePath);
        String ext = paths.get(paths.size() - 1);
        if (!Arrays.asList("mp4", "avi", "rmvb", "rm", "mkv", "flv", "mov", "wmv", "asf", "3gp", "dat", "ts", "mts", "vob").contains(ext)){
            throw new RuntimeException("不支持的文件格式");
        }
        String resultPath = Joiner.on(File.separator).join(Arrays.asList(outputDir, UUID.randomUUID().toString() + "." + ext));
        //加载FFmpeg库
//        String ffmpeg = Loader.load(ffmpeg.class);
        String ffmpeg = "D:\\JAVA\\ffmpeg\\ffmpeg-master-latest-win64-gpl-shared\\bin\\ffmpeg.exe";  // 替换为实际的路径
        ProcessBuilder builder = new ProcessBuilder(
                ffmpeg,
                "-i",
                imagePath,
                "-r",
                String.valueOf(30),//设置帧率
                "-c:v",
                "libx264", // 设置视频编码器
                "-s",
                MessageFormat.format("{0}x{1}",String.valueOf(width), String.valueOf(height)),
//                "-b",
//                MessageFormat.format("{0}k", String.valueOf(bitRate)),
                resultPath);
        // 定义 FFmpeg 命令
//        String command = "ffmpeg -i " + imagePath + " -s "+MessageFormat.format("{0}x{1}",String.valueOf(width), String.valueOf(height))+" -c:v libx264 " + resultPath;
//
//        ProcessBuilder builder = new ProcessBuilder(command.split(" "));
        try {

            Process process = builder.inheritIO().start();
            boolean success = process.waitFor(10, TimeUnit.MINUTES);
            if (!success) {
                // 处理进程超时的情况
                process.destroyForcibly();
                throw new RuntimeException("视频处理超时");
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
            // 处理异常情况
            throw new RuntimeException("视频处理过程中出错", e);
        }
        return resultPath;
    }
//    public static void test2(String inputPath,String outputPath,int targetWidth, int targetHeight)throws Exception{
//        try {
//            // 创建输入和输出帧抓取器
//            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputPath);
//            grabber.start();
//
//            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputPath, targetWidth, targetHeight);
//            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
//            recorder.setFormat("mp4");
//            recorder.setFrameRate(grabber.getFrameRate());
//            recorder.setVideoBitrate(grabber.getVideoBitrate());
//            recorder.start();
//
//            // 创建 Java2DFrameConverter
//            Java2DFrameConverter converter = new Java2DFrameConverter();
//
//            // 读取和写入帧
//            Frame frame;
//            while ((frame = grabber.grabFrame()) != null) {
//                // 将帧转换为 Java 2D 图像
//                BufferedImage image = converter.convert(frame);
//
//                // 降低分辨率
//                BufferedImage resizedImage = resizeImage(image, targetWidth, targetHeight);
//
//                // 将 Java 2D 图像转换回帧
//                frame = converter.convert(resizedImage);
//
//                recorder.record(frame);
//            }
//
//            // 关闭资源
//            grabber.stop();
//            grabber.release();
//            recorder.stop();
//            recorder.release();
//
//            System.out.println("视频清晰度调整成功！");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = resizedImage.createGraphics();
        g2d.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        g2d.dispose();
        return resizedImage;
    }

    /**
     * 视频转成Mp4
     *
     * @param sourceFile
     * @param distFile
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp4(String sourceFile, String distFile, EncoderProgressListener pListener) throws EncoderException {
        File source = new File(sourceFile);
        File target = new File(distFile);
        if (target.exists()) {
            target.delete();
        }
        AudioAttributes audioAttr = new AudioAttributes();
        VideoAttributes videoAttr = new VideoAttributes();
        EncodingAttributes encodingAttr = new EncodingAttributes();
        audioAttr.setChannels(2);
        audioAttr.setCodec("aac");
        audioAttr.setBitRate(128000);
        audioAttr.setSamplingRate(44100);
        videoAttr.setCodec("libx264");
        videoAttr.setBitRate(2 * 1024 * 1024);
        videoAttr.setSize(new VideoSize(1080, 720));
        videoAttr.setFaststart(true);
        videoAttr.setFrameRate(29);
        encodingAttr.setAudioAttributes(audioAttr);
        encodingAttr.setVideoAttributes(videoAttr);
        encodingAttr.setOutputFormat("mp4");
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(source), target, encodingAttr, pListener);
    }

    /**
     * 视频加图片水印
     *
     * @param sourceFile
     * @param distFile
     * @param waterMark
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp4WithWaterMark(String sourceFile, String distFile, String waterMark, EncoderProgressListener pListener) throws EncoderException {
        File sourceVideo = new File(sourceFile);
        File watermark = new File(waterMark);
        VideoAttributes vidAttr = new VideoAttributes();
        vidAttr.addFilter(new OverlayWatermark(watermark, OverlayLocation.BOTTOM_RIGHT, -10, -10));
        EncodingAttributes encAttr = new EncodingAttributes().setVideoAttributes(vidAttr);
        File target = new File(distFile);
        new Encoder().encode(new MultimediaObject(sourceVideo), target, encAttr, pListener);
    }



    public static String addAPictureWatermark(String inputVideo,String watermarkImage,String outputVideo){
//        String ffmpeg = "D:\\JAVA\\ffmpeg\\ffmpeg-master-latest-win64-gpl-shared\\bin\\ffmpeg.exe";
        // FFmpeg命令ffmpeg -i input_video.mp4 -i watermark.png -filter_complex "overlay=10:10" -c:a copy output_video.mp4
        String command =  "ffmpeg -i " + inputVideo + " -i " + watermarkImage + " -filter_complex \"overlay=x=10:y=10\" " +" -c:a copy" + outputVideo;
        ProcessBuilder builder = new ProcessBuilder("ffmpeg", "-i", inputVideo, "-i", watermarkImage, "-filter_complex", "overlay=x=10:y=10", "-c:a", "copy", outputVideo);

        try {

            Process process = builder.inheritIO().start();
            boolean success = process.waitFor(10, TimeUnit.MINUTES);
            if (!success) {
                // 处理进程超时的情况
                process.destroyForcibly();
                throw new RuntimeException("视频处理超时");
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
            // 处理异常情况
            throw new RuntimeException("视频处理过程中出错", e);
        }
        return outputVideo;
    }


    public static String addAWriteWatermark(String inputVideo,String text,String outputVideo){
//        String ffmpeg = "D:\\JAVA\\ffmpeg\\ffmpeg-master-latest-win64-gpl-shared\\bin\\ffmpeg.exe";
        // FFmpeg命令ffmpeg -i input_video.mp4 -vf "drawtext=text='Hello World':fontsize=24:fontcolor=white:x=10:y=10" output_video.mp4
        ProcessBuilder builder = new ProcessBuilder("ffmpeg", "-i", inputVideo, "-vf", "drawtext=text='" + text + "':fontsize=24:fontcolor=white:x=10:y=10","-y", outputVideo);
        try {

            Process process = builder.inheritIO().start();
            boolean success = process.waitFor(10, TimeUnit.MINUTES);
            if (!success) {
                // 处理进程超时的情况
                process.destroyForcibly();
                throw new RuntimeException("视频处理超时");
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
            // 处理异常情况
            throw new RuntimeException("视频处理过程中出错", e);
        }
        return outputVideo;
    }

    @Autowired
    private CommonInfoService commonRepository;


    /**
     * 选择是否添加水印
     * @param inputVideo
     * @param watermarkImage
     * @param outputVideo
     * @throws Exception
     */
    public void addWatermark(String inputVideo,String watermarkImage,String outputVideo)throws Exception{
//        CommonInfo http = commonRepository.findOne(19);
//        String[] split = uploadVo.getFileUrl().split("//");
//        //原始文件
//        Path path = Paths.get("/www/wwwroot/"+split[1]);
//        if (!Files.exists(Paths.get("/www/wwwroot/duanju/temporary"))){
//            Files.createDirectory(Paths.get("/www/wwwroot/duanju/temporary"));
//        }
//        //获取文件后缀
//        String suffix = FilenameUtils.getExtension(uploadVo.getFileUrl());
//        // 生成临时输入文件路径
//        String str = "/www/wwwroot/duanju/temporary/" + UUID.randomUUID().toString() + "." + suffix;
//        Path toPath = Paths.get(str);
//        try {
//            addAWriteWatermark(path.toString(),"7wang", toPath.toString());
//            // 删除原始输入文件
//            Files.delete(path);
//            //        复制文件
//            Files.copy(toPath, path);
//            //删除临时文件
//            Files.delete(toPath);
//        }catch (Exception e){
//            e.printStackTrace();
//            throw new Exception("添加水印失败");
//        }
    }

    //获取视频时长
    public static String getVideoDuration(String videoPath) throws Exception {
        String duration = null;
        try {
            ProcessBuilder builder = new ProcessBuilder("ffmpeg", "-i", videoPath);
            Process process = builder.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains("Duration:")) {
                    duration = line.split(",")[0].split("Duration:")[1].trim();
                    break;
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("获取视频时长失败");
        }
        return duration;
    }

}
